package com.threeti.mecool.core.domain.model.plan.pojo;

import com.threeti.mecool.core.domain.model.project.Project;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectRepository;
import org.codehaus.jackson.annotate.JsonBackReference;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonManagedReference;
import org.springframework.beans.factory.annotation.Configurable;

import javax.annotation.Resource;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Configurable
@Entity
@Table(name = "DM_PLAN_PROJECT")
public class PlanProject {
    private Long id;
    private Integer version;
    private Plan plan;
    private String projectCode;
    private String projectName;
    private List<PlanJob> planJobs = new ArrayList<PlanJob>();
    private ProjectRepository projectRepository;

    public void addPlanJob(PlanJob planJob) {
        planJob.setPlanProject(this);
        planJobs.add(planJob);
    }

    public PlanJob optPlanJobByJobIdAndStoreCode(Long jobId, String storeCode) {
        for (PlanJob planJob : planJobs) {
            if (jobId.equals(planJob.getJobId()) && storeCode.equals(planJob.getStoreCode())) {
                return planJob;
            }
        }
        PlanJob planJob = new PlanJob();
        Job job = Job.findById(jobId);
        planJob.setJob(job);
        planJob.setStoreCode(storeCode);
        addPlanJob(planJob);
        return planJob;
    }

    //<editor-fold desc="get/set">
    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    @JsonManagedReference("planJobs")
    @OneToMany(mappedBy = "planProject", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<PlanJob> getPlanJobs() {
        return planJobs;
    }

    public String getProjectCode() {
        return projectCode;
    }

    @JsonBackReference
    @ManyToOne
    public Plan getPlan() {
        return plan;
    }

    @Transient
    public String getProjectName() {
        if (projectCode == null) throw new RuntimeException("Project Code should not be NULL");
        if (projectName == null) {
            Project project = projectRepository.findByCode(projectCode);
            if (project != null) {
                projectName = project.getName();
            } else {
                // fast failure
//                throw new RuntimeException("PlanProject - Invalid Project Code: " + projectCode);
                return "";
            }
        }
        return projectName;
    }


    @Transient
    public Long getProjectId() {
        Project project = projectRepository.findByCode(projectCode);
        if (project != null) {
            return project.getId();
        } else {
            return 0L;
        }
    }

    @Transient
    @JsonIgnore
    public Project getProject() {
        return projectRepository.findByCode(projectCode);
    }

    @Resource
    public void setProjectRepository(ProjectRepository projectRepository) {
        this.projectRepository = projectRepository;
    }

    public void setPlan(Plan plan) {
        this.plan = plan;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setPlanJobs(List<PlanJob> planJobs) {
        this.planJobs = planJobs;
    }

    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }
    //</editor-fold>
}
